package arithmetic.socket.nio;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * buffer 的聚合和分散 Gathering he Sacttering
 * 便于自定义协议中 各部分数据的分明别类
 *
 * @author jiangfeng
 * Created on 2020-03-26
 */
public class NioTest4 {
    public static void main(String[] args) throws Exception {

        // 老师的写法
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress(8899);
        serverSocketChannel.socket().bind(address);

         // 我的写法
        //ServerSocket serverSocket = new ServerSocket(8899);
        int messageLength = 2 + 3 + 4;

        ByteBuffer[] byteBuffers = new ByteBuffer[3];
        byteBuffers[0] = ByteBuffer.allocate(2);
        byteBuffers[1] = ByteBuffer.allocate(3);
        byteBuffers[2] = ByteBuffer.allocate(4);

        while (true) {
            System.out.println("等待客户端连接");
            SocketChannel channel = serverSocketChannel.accept();
            System.out.println("客户端连接成功:"+channel.getRemoteAddress());

            long bufferRead = 0;
            while (bufferRead < messageLength) {
                long read = channel.read(byteBuffers);
                bufferRead += read;
                System.out.println("bytesRead: " + bufferRead);
                Arrays.asList(byteBuffers).stream().map(buffer ->buffer.position() +" "+buffer.limit()).forEach(System.out::println);
            }
            // 先翻转下
            // Arrays.asList(byteBuffers).stream().forEach(Buffer::flip);
            Arrays.stream(byteBuffers).forEach(Buffer::flip);

            // 写会sockertChannel
            long bytesWritten = 0;
            while (bytesWritten < messageLength) {
                long r = channel.write(byteBuffers);
                bytesWritten += r;
            }
            Arrays.asList(byteBuffers).stream().map(buffer ->buffer.position() +" "+buffer.limit()).forEach(System.out::println);

            channel.write(byteBuffers);
            // 最后清除下
            Arrays.asList(byteBuffers).stream().forEach(buffer->buffer.clear());
        }
    }
}
